# !/usr/bin/env python3
# -*- coding: utf-8 -*-


import xml.etree.ElementTree as EleTree
from util.lib import pretty_xml, get_node_type


def _init_mac_tbl_xml(mac_set, mac_tbl_xml):
    root = EleTree.Element('mac_tbl')
    for entry in mac_set:
        node_ele = EleTree.SubElement(root, 'node')
        node_id_ele = EleTree.SubElement(node_ele, 'node_id')
        node_id_ele.text = str(entry['node_id'])
        broadcast_flag_ele = EleTree.SubElement(node_ele, 'broadcast_flag')
        broadcast_flag_ele.text = str(entry['broadcast_flag'])
        for mac_entry in entry['tbl_each_node']:
            entry_ele = EleTree.SubElement(node_ele, 'entry')
            valid_ele = EleTree.SubElement(entry_ele, 'valid')
            valid_ele.text = '1'
            reserve1_ele = EleTree.SubElement(entry_ele, 'reserve1')
            reserve1_ele.text = '0'
            outport1_ele = EleTree.SubElement(entry_ele, 'outport1')
            outport1_ele.text = str((mac_entry['outport'] & 0x1FFFE0000) >> 17)
            outport2_ele = EleTree.SubElement(entry_ele, 'outport2')
            outport2_ele.text = str(mac_entry['outport'] & 0x1FFFF)
            dmac_1_ele = EleTree.SubElement(entry_ele, 'dmac_1')
            dmac = mac_entry['mac'].split(':')
            dmac_1 = '0x'
            dmac_2 = '0x'
            for item in dmac[:2]:
                dmac_1 += item
            for item in dmac[2:]:
                dmac_2 += item
            dmac_1_ele.text = dmac_1
            dmac_2_ele = EleTree.SubElement(entry_ele, 'dmac_2')
            dmac_2_ele.text = dmac_2
            reserve2_ele = EleTree.SubElement(entry_ele, 'reserve2')
            reserve2_ele.text = '0'
    tree = EleTree.ElementTree(root)
    pretty_xml(root, '\t', '\n')
    tree.write(mac_tbl_xml,
               encoding='utf-8',
               xml_declaration=True)


def _get_mac_tbl(mac_xml,node_type_set):
    mac_set = []

    root = EleTree.parse(mac_xml)
    node_ele_set = root.findall('node')
    for node_ele in node_ele_set:
        node = {}
        node_id = node_ele.findtext('node_id')
        node_id = int(node_id, 16)
        for node_type in node_type_set:
            if node_type['node_id'] == node_id and node_type['node_type'] == 0:
                broadcast_flag = node_ele.findtext('broadcast_flag')
                broadcast_flag = int(broadcast_flag, 16)
                node.update({'node_id': node_id,
                             'broadcast_flag': broadcast_flag})
                tbl_each_node = []
                tbl_ele = node_ele.find('mac_forward_table')
                entry_ele_set = tbl_ele.findall('entry')
                for entry_ele in entry_ele_set:
                    mac_addr = entry_ele.findtext('mac')
                    outport = entry_ele.findtext('outport')
                    outport = int(outport, 16)
                    tbl_each_node.append({'mac': mac_addr,
                                          'outport': outport})
                node.update({'tbl_each_node': tbl_each_node})
                mac_set.append(node)

    return mac_set


def assemble_mac_tbl(mac_xml, para_xml,
                     mac_tbl_xml):

    # 1.根据para_xml，获取设备节点的类型，node_type_set
    node_type_set = get_node_type(para_xml)
    print("1. node_type_set: ")
    [print(entry) for entry in node_type_set]

    # 2.根据static_mac_cfg.xml，获取mac转发表信息
    mac_set = _get_mac_tbl(mac_xml, node_type_set)
    print("2. mac_set: ")
    [print(entry) for entry in mac_set]

    # 生成xml
    _init_mac_tbl_xml(mac_set, mac_tbl_xml)
    return


def main():
    mac_xml = '../input/static_mac_cfg.xml'
    mac_tbl_xml = '../output/tbl/mac_tbl.xml'
    para_xml = '../input/cfg_parameter.xml'
    assemble_mac_tbl(mac_xml, para_xml, mac_tbl_xml)


if __name__ == '__main__':
    main()
